package com.yh.supergo.page.service;

import com.alibaba.fastjson.JSON;
import com.yh.supergo.http.HttpResult;
import com.yh.supergo.manager.feign.GoodsFeignClient;
import com.yh.supergo.manager.feign.ItemCatFeignClient;
import com.yh.supergo.page.config.GoodsLock;
import com.yh.supergo.pojo.Goods;
import com.yh.supergo.pojo.Goodsdesc;
import com.yh.supergo.pojo.Item;
import com.yh.supergo.pojo.Itemcat;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName PageService
 * @Description TODO
 * @Author 0715-YuHao
 * @Date 2020/11/21 10:33
 */
@Service
public class PageService {

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private GoodsFeignClient goodsFeign;

    @Autowired
    private ItemCatFeignClient itemCatFeign;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private GoodsLock goodsLock;

    /**
     * @Author 0715-YuHao
     * @Description 生成静态页面业务逻辑
     * @Date 2020/11/21 10:35
     * @Param [goodsId] 商品Id
     * @return com.yh.supergo.http.HttpResult
     */
    public HttpResult buildGoodsPage(long goodsId) throws IOException {
        FileWriter fileWriter = new FileWriter("d:/test/temp/goods/"+goodsId+".html");
        Context context = getGoodsData(goodsId);
        templateEngine.process("item", context, fileWriter);
        fileWriter.close();
        return HttpResult.ok();
    }

    private Context getGoodsData(long goodsId) {
        Context context = new Context();
        // Goods、
        Goods goods = goodsFeign.getGoodsById(goodsId);
        //查询商品的分类 3个分类
        Itemcat itemCat1 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        Itemcat itemCat2 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        Itemcat itemCat3 = itemCatFeign.getItemCatById(goods.getCategory1Id());
        // GoodsDesc、
        //GoodsDesc goodsDesc = goodsDescMapper.selectByPrimaryKey(goodsId);
        Goodsdesc goodsDesc = goodsFeign.getGoodsDescById(goodsId);
        //获取图片列表
        String jsonImages = goodsDesc.getItemImages();
        if (StringUtils.isNotBlank(jsonImages)) {
            try {
                List<Map> imagesList = JSON.parseArray(jsonImages, Map.class);
                context.setVariable("itemImageList", imagesList);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //获取属性信息
        String jsonCustomAttributeItems = goodsDesc.getCustomAttributeItems();
        if (StringUtils.isNotBlank(jsonCustomAttributeItems)) {
            try {
                List<Map> customAttributeList = JSON.parseArray(jsonCustomAttributeItems,
                        Map.class);
                context.setVariable("customAttributeList", customAttributeList);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //提取规格数据
        String jsonSpecificationItems = goodsDesc.getSpecificationItems();
        if (StringUtils.isNotBlank(jsonSpecificationItems)) {
            try {
                List<Map> specificationItems = JSON.parseArray(jsonSpecificationItems,Map.class);
                context.setVariable("specificationList", specificationItems);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // List<Item>
        List<Item> itemList = goodsFeign.getItemList(goodsId);
        context.setVariable("goods", goods);
        context.setVariable("goodsDesc", goodsDesc);
        context.setVariable("itemCat1", itemCat1);
        context.setVariable("itemCat2", itemCat2);
        context.setVariable("itemCat3", itemCat3);
        context.setVariable("itemList", itemList);
        return context;
    }

    /**
     * @return java.util.Map<java.lang.Object, java.lang.Object>
     * @Author 0715-YuHao
     * @Description 查询商品库存
     * @Date 2020/11/21 11:23
     * @Param [商品id]
     */
    public Map<Object, Object> getItemStocks(long spuId) {
        //防止缓存穿透，非法Id直接返回null
        if (spuId <= 0) {
            Map<Object, Object> result = new HashMap<>();
            result.put("0", "0");
            return result;
        }
        //查询缓存
        Map<Object, Object> entries = redisTemplate.opsForHash().entries("goods-stock:" + spuId);
        if (entries != null && !entries.isEmpty()) {
            return entries;
        }
        //获得spuId对应的lock,保证只能有一个线程访问一个商品
        ReentrantLock lock = goodsLock.getLock(spuId);
        if (lock.tryLock()) {
            //查询数据库
            List<Item> itemList = goodsFeign.getItemList(spuId);
            if (itemList == null || itemList.isEmpty()) {
                redisTemplate.opsForHash().put("goods-stock:" + spuId, "0", "0");
                redisTemplate.expire("goods-stock:" + spuId, 5, TimeUnit.MINUTES);
                Map<Object, Object> result = new HashMap<>();
                result.put("0", "0");
                return result;
            }
            Map<Object, Object> result = new HashMap<>();
            itemList.forEach(item -> {
                result.put(item.getId(), item.getNum());
                redisTemplate.opsForHash().put("goods-stock:" + spuId, item.getId().toString(), item.getNum().toString());
            });
            redisTemplate.expire("goods-stock:", 1, TimeUnit.DAYS);
            //释放锁
            lock.unlock();
            goodsLock.removeLock(spuId);
            return result;
        }else {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return getItemStocks(spuId);
        }
    }
}
